Commit | Line | Data |
---|---|---|
15637ed4 RG |
1 | // This may look like C code, but it is really -*- C++ -*- |
2 | /* | |
3 | Copyright (C) 1988 Free Software Foundation | |
4 | written by Doug Lea (dl@rocky.oswego.edu) | |
5 | ||
6 | This file is part of GNU CC. | |
7 | ||
8 | GNU CC is distributed in the hope that it will be useful, | |
9 | but WITHOUT ANY WARRANTY. No author or distributor | |
10 | accepts responsibility to anyone for the consequences of using it | |
11 | or for whether it serves any particular purpose or works at all, | |
12 | unless he says so in writing. Refer to the GNU CC General Public | |
13 | License for full details. | |
14 | ||
15 | Everyone is granted permission to copy, modify and redistribute | |
16 | GNU CC, but only under the conditions described in the | |
17 | GNU CC General Public License. A copy of this license is | |
18 | supposed to have been given to you along with GNU CC so you | |
19 | can know your rights and responsibilities. It should be in a | |
20 | file named COPYING. Among other things, the copyright notice | |
21 | and this notice must be preserved on all copies. | |
22 | */ | |
23 | ||
24 | #if defined(SHORT_NAMES) || defined(VMS) | |
25 | #define re_compile_pattern recmppat | |
26 | #define re_pattern_buffer repatbuf | |
27 | #define re_registers reregs | |
28 | #endif | |
29 | ||
30 | #ifndef _String_h | |
31 | #ifdef __GNUG__ | |
32 | #pragma once | |
33 | #pragma interface | |
34 | #endif | |
35 | #define _String_h 1 | |
36 | ||
37 | #include <stream.h> | |
38 | #include <Regex.h> | |
39 | ||
40 | struct StrRep // internal String representations | |
41 | { | |
42 | unsigned short len; // string length | |
43 | unsigned short sz; // allocated space | |
44 | char s[1]; // the string starts here | |
45 | // (at least 1 char for trailing null) | |
46 | // allocated & expanded via non-public fcts | |
47 | }; | |
48 | ||
49 | // primitive ops on StrReps -- nearly all String fns go through these. | |
50 | ||
51 | StrRep* Salloc(StrRep*, const char*, int, int); | |
52 | StrRep* Scopy(StrRep*, StrRep*); | |
53 | StrRep* Sresize(StrRep*, int); | |
54 | StrRep* Scat(StrRep*, const char*, int, const char*, int); | |
55 | StrRep* Scat(StrRep*, const char*, int,const char*,int, const char*,int); | |
56 | StrRep* Sprepend(StrRep*, const char*, int); | |
57 | StrRep* Sreverse(StrRep*, StrRep*); | |
58 | StrRep* Supcase(StrRep*, StrRep*); | |
59 | StrRep* Sdowncase(StrRep*, StrRep*); | |
60 | StrRep* Scapitalize(StrRep*, StrRep*); | |
61 | ||
62 | // These classes need to be defined in the order given | |
63 | ||
64 | class String; | |
65 | class SubString; | |
66 | ||
67 | class SubString | |
68 | { | |
69 | friend class String; | |
70 | protected: | |
71 | ||
72 | String& S; // The String I'm a substring of | |
73 | unsigned short pos; // starting position in S's rep | |
74 | unsigned short len; // length of substring | |
75 | ||
76 | void assign(StrRep*, const char*, int = -1); | |
77 | SubString(String& x, int p, int l); | |
78 | SubString(const SubString& x); | |
79 | ||
80 | public: | |
81 | ||
82 | // Note there are no public constructors. SubStrings are always | |
83 | // created via String operations | |
84 | ||
85 | ~SubString(); | |
86 | ||
87 | void operator = (const String& y); | |
88 | void operator = (const SubString& y); | |
89 | void operator = (const char* t); | |
90 | void operator = (char c); | |
91 | ||
92 | // return 1 if target appears anywhere in SubString; else 0 | |
93 | ||
94 | int contains(char c) const; | |
95 | int contains(const String& y) const; | |
96 | int contains(const SubString& y) const; | |
97 | int contains(const char* t) const; | |
98 | int contains(const Regex& r) const; | |
99 | ||
100 | // return 1 if target matches entire SubString | |
101 | ||
102 | int matches(const Regex& r) const; | |
103 | ||
104 | // IO | |
105 | ||
106 | friend ostream& operator<<(ostream& s, const SubString& x); | |
107 | ||
108 | // status | |
109 | ||
110 | int length() const; | |
111 | int empty() const; | |
112 | const char* chars() const; | |
113 | ||
114 | int OK() const; | |
115 | ||
116 | }; | |
117 | ||
118 | ||
119 | class String | |
120 | { | |
121 | friend class SubString; | |
122 | ||
123 | protected: | |
124 | StrRep* rep; // Strings are pointers to their representations | |
125 | ||
126 | // some helper functions | |
127 | ||
128 | int search(int, int, const char*, int = -1) const; | |
129 | int search(int, int, char) const; | |
130 | int match(int, int, int, const char*, int = -1) const; | |
131 | int _gsub(const char*, int, const char* ,int); | |
132 | int _gsub(const Regex&, const char*, int); | |
133 | SubString _substr(int, int); | |
134 | ||
135 | public: | |
136 | ||
137 | // constructors & assignment | |
138 | ||
139 | String(); | |
140 | String(const String& x); | |
141 | String(const SubString& x); | |
142 | String(const char* t); | |
143 | String(const char* t, int len); | |
144 | String(char c); | |
145 | ||
146 | ~String(); | |
147 | ||
148 | void operator = (const String& y); | |
149 | void operator = (const char* y); | |
150 | void operator = (char c); | |
151 | void operator = (const SubString& y); | |
152 | ||
153 | // concatenation | |
154 | ||
155 | void operator += (const String& y); | |
156 | void operator += (const SubString& y); | |
157 | void operator += (const char* t); | |
158 | void operator += (char c); | |
159 | ||
160 | void prepend(const String& y); | |
161 | void prepend(const SubString& y); | |
162 | void prepend(const char* t); | |
163 | void prepend(char c); | |
164 | ||
165 | ||
166 | // procedural versions: | |
167 | // concatenate first 2 args, store result in last arg | |
168 | ||
169 | friend void cat(const String&, const String&, String&); | |
170 | friend void cat(const String&, const SubString&, String&); | |
171 | friend void cat(const String&, const char*, String&); | |
172 | friend void cat(const String&, char, String&); | |
173 | ||
174 | friend void cat(const SubString&, const String&, String&); | |
175 | friend void cat(const SubString&, const SubString&, String&); | |
176 | friend void cat(const SubString&, const char*, String&); | |
177 | friend void cat(const SubString&, char, String&); | |
178 | ||
179 | friend void cat(const char*, const String&, String&); | |
180 | friend void cat(const char*, const SubString&, String&); | |
181 | friend void cat(const char*, const char*, String&); | |
182 | friend void cat(const char*, char, String&); | |
183 | ||
184 | // double concatenation, by request. (yes, there are too many versions, | |
185 | // but if one is supported, then the others should be too...) | |
186 | // Concatenate first 3 args, store in last arg | |
187 | ||
188 | friend void cat(const String&,const String&, const String&,String&); | |
189 | friend void cat(const String&,const String&,const SubString&,String&); | |
190 | friend void cat(const String&,const String&, const char*, String&); | |
191 | friend void cat(const String&,const String&, char, String&); | |
192 | friend void cat(const String&,const SubString&,const String&,String&); | |
193 | friend void cat(const String&,const SubString&,const SubString&,String&); | |
194 | friend void cat(const String&,const SubString&, const char*, String&); | |
195 | friend void cat(const String&,const SubString&, char, String&); | |
196 | friend void cat(const String&,const char*, const String&, String&); | |
197 | friend void cat(const String&,const char*, const SubString&, String&); | |
198 | friend void cat(const String&,const char*, const char*, String&); | |
199 | friend void cat(const String&,const char*, char, String&); | |
200 | ||
201 | friend void cat(const char*, const String&, const String&,String&); | |
202 | friend void cat(const char*,const String&,const SubString&,String&); | |
203 | friend void cat(const char*,const String&, const char*, String&); | |
204 | friend void cat(const char*,const String&, char, String&); | |
205 | friend void cat(const char*,const SubString&,const String&,String&); | |
206 | friend void cat(const char*,const SubString&,const SubString&,String&); | |
207 | friend void cat(const char*,const SubString&, const char*, String&); | |
208 | friend void cat(const char*,const SubString&, char, String&); | |
209 | friend void cat(const char*,const char*, const String&, String&); | |
210 | friend void cat(const char*,const char*, const SubString&, String&); | |
211 | friend void cat(const char*,const char*, const char*, String&); | |
212 | friend void cat(const char*,const char*, char, String&); | |
213 | ||
214 | ||
215 | // searching & matching | |
216 | ||
217 | // return position of target in string or -1 for failure | |
218 | ||
219 | int index(char c, int startpos = 0) const; | |
220 | int index(const String& y, int startpos = 0) const; | |
221 | int index(const SubString& y, int startpos = 0) const; | |
222 | int index(const char* t, int startpos = 0) const; | |
223 | int index(const Regex& r, int startpos = 0) const; | |
224 | ||
225 | // return 1 if target appears anyhere in String; else 0 | |
226 | ||
227 | int contains(char c) const; | |
228 | int contains(const String& y) const; | |
229 | int contains(const SubString& y) const; | |
230 | int contains(const char* t) const; | |
231 | int contains(const Regex& r) const; | |
232 | ||
233 | // return 1 if target appears anywhere after position pos | |
234 | // (or before, if pos is negative) in String; else 0 | |
235 | ||
236 | int contains(char c, int pos) const; | |
237 | int contains(const String& y, int pos) const; | |
238 | int contains(const SubString& y, int pos) const; | |
239 | int contains(const char* t, int pos) const; | |
240 | int contains(const Regex& r, int pos) const; | |
241 | ||
242 | // return 1 if target appears at position pos in String; else 0 | |
243 | ||
244 | int matches(char c, int pos = 0) const; | |
245 | int matches(const String& y, int pos = 0) const; | |
246 | int matches(const SubString& y, int pos = 0) const; | |
247 | int matches(const char* t, int pos = 0) const; | |
248 | int matches(const Regex& r, int pos = 0) const; | |
249 | ||
250 | // return number of occurences of target in String | |
251 | ||
252 | int freq(char c) const; | |
253 | int freq(const String& y) const; | |
254 | int freq(const SubString& y) const; | |
255 | int freq(const char* t) const; | |
256 | ||
257 | // SubString extraction | |
258 | ||
259 | // Note that you can't take a substring of a const String, since | |
260 | // this leaves open the possiblility of indirectly modifying the | |
261 | // String through the SubString | |
262 | ||
263 | SubString at(int pos, int len); | |
264 | SubString operator () (int pos, int len); // synonym for at | |
265 | ||
266 | SubString at(const String& x, int startpos = 0); | |
267 | SubString at(const SubString& x, int startpos = 0); | |
268 | SubString at(const char* t, int startpos = 0); | |
269 | SubString at(char c, int startpos = 0); | |
270 | SubString at(const Regex& r, int startpos = 0); | |
271 | ||
272 | SubString before(int pos); | |
273 | SubString before(const String& x, int startpos = 0); | |
274 | SubString before(const SubString& x, int startpos = 0); | |
275 | SubString before(const char* t, int startpos = 0); | |
276 | SubString before(char c, int startpos = 0); | |
277 | SubString before(const Regex& r, int startpos = 0); | |
278 | ||
279 | SubString through(int pos); | |
280 | SubString through(const String& x, int startpos = 0); | |
281 | SubString through(const SubString& x, int startpos = 0); | |
282 | SubString through(const char* t, int startpos = 0); | |
283 | SubString through(char c, int startpos = 0); | |
284 | SubString through(const Regex& r, int startpos = 0); | |
285 | ||
286 | SubString from(int pos); | |
287 | SubString from(const String& x, int startpos = 0); | |
288 | SubString from(const SubString& x, int startpos = 0); | |
289 | SubString from(const char* t, int startpos = 0); | |
290 | SubString from(char c, int startpos = 0); | |
291 | SubString from(const Regex& r, int startpos = 0); | |
292 | ||
293 | SubString after(int pos); | |
294 | SubString after(const String& x, int startpos = 0); | |
295 | SubString after(const SubString& x, int startpos = 0); | |
296 | SubString after(const char* t, int startpos = 0); | |
297 | SubString after(char c, int startpos = 0); | |
298 | SubString after(const Regex& r, int startpos = 0); | |
299 | ||
300 | ||
301 | // deletion | |
302 | ||
303 | // delete len chars starting at pos | |
304 | void del(int pos, int len); | |
305 | ||
306 | // delete the first occurrence of target after startpos | |
307 | ||
308 | void del(const String& y, int startpos = 0); | |
309 | void del(const SubString& y, int startpos = 0); | |
310 | void del(const char* t, int startpos = 0); | |
311 | void del(char c, int startpos = 0); | |
312 | void del(const Regex& r, int startpos = 0); | |
313 | ||
314 | // global substitution: substitute all occurrences of pat with repl | |
315 | ||
316 | int gsub(const String& pat, const String& repl); | |
317 | int gsub(const SubString& pat, const String& repl); | |
318 | int gsub(const char* pat, const String& repl); | |
319 | int gsub(const char* pat, const char* repl); | |
320 | int gsub(const Regex& pat, const String& repl); | |
321 | ||
322 | // friends & utilities | |
323 | ||
324 | // split string into array res at separators; return number of elements | |
325 | ||
326 | friend int split(const String& x, String res[], int maxn, | |
327 | const String& sep); | |
328 | friend int split(const String& x, String res[], int maxn, | |
329 | const Regex& sep); | |
330 | ||
331 | friend String common_prefix(const String& x, const String& y, | |
332 | int startpos = 0); | |
333 | friend String common_suffix(const String& x, const String& y, | |
334 | int startpos = -1); | |
335 | friend String replicate(char c, int n); | |
336 | friend String replicate(const String& y, int n); | |
337 | friend String join(String src[], int n, const String& sep); | |
338 | ||
339 | // simple builtin transformations | |
340 | ||
341 | friend String reverse(const String& x); | |
342 | friend String upcase(const String& x); | |
343 | friend String downcase(const String& x); | |
344 | friend String capitalize(const String& x); | |
345 | ||
346 | // in-place versions of above | |
347 | ||
348 | void reverse(); | |
349 | void upcase(); | |
350 | void downcase(); | |
351 | void capitalize(); | |
352 | ||
353 | // element extraction | |
354 | ||
355 | char& operator [] (int i); | |
356 | char elem(int i) const; | |
357 | char firstchar() const; | |
358 | char lastchar() const; | |
359 | ||
360 | // conversion | |
361 | ||
362 | operator const char*() const; | |
363 | const char* chars() const; | |
364 | ||
365 | ||
366 | // IO | |
367 | ||
368 | friend ostream& operator<<(ostream& s, const String& x); | |
369 | friend ostream& operator<<(ostream& s, const SubString& x); | |
370 | friend istream& operator>>(istream& s, String& x); | |
371 | ||
372 | friend int readline(istream& s, String& x, | |
373 | char terminator = '\n', | |
374 | int discard_terminator = 1); | |
375 | ||
376 | // status | |
377 | ||
378 | int length() const; | |
379 | int empty() const; | |
380 | ||
381 | // preallocate some space for String | |
382 | void alloc(int newsize); | |
383 | ||
384 | // report current allocation (not length!) | |
385 | ||
386 | int allocation() const; | |
387 | ||
388 | ||
389 | volatile void error(const char* msg) const; | |
390 | ||
391 | int OK() const; | |
392 | }; | |
393 | ||
394 | typedef String StrTmp; // for backward compatibility | |
395 | ||
396 | // other externs | |
397 | ||
398 | int compare(const String& x, const String& y); | |
399 | int compare(const String& x, const SubString& y); | |
400 | int compare(const String& x, const char* y); | |
401 | int compare(const SubString& x, const String& y); | |
402 | int compare(const SubString& x, const SubString& y); | |
403 | int compare(const SubString& x, const char* y); | |
404 | int fcompare(const String& x, const String& y); // ignore case | |
405 | ||
406 | extern StrRep _nilStrRep; | |
407 | extern String _nilString; | |
408 | ||
409 | // other inlines | |
410 | ||
411 | String operator + (const String& x, const String& y); | |
412 | String operator + (const String& x, const SubString& y); | |
413 | String operator + (const String& x, const char* y); | |
414 | String operator + (const String& x, char y); | |
415 | String operator + (const SubString& x, const String& y); | |
416 | String operator + (const SubString& x, const SubString& y); | |
417 | String operator + (const SubString& x, const char* y); | |
418 | String operator + (const SubString& x, char y); | |
419 | String operator + (const char* x, const String& y); | |
420 | String operator + (const char* x, const SubString& y); | |
421 | ||
422 | int operator==(const String& x, const String& y); | |
423 | int operator!=(const String& x, const String& y); | |
424 | int operator> (const String& x, const String& y); | |
425 | int operator>=(const String& x, const String& y); | |
426 | int operator< (const String& x, const String& y); | |
427 | int operator<=(const String& x, const String& y); | |
428 | int operator==(const String& x, const SubString& y); | |
429 | int operator!=(const String& x, const SubString& y); | |
430 | int operator> (const String& x, const SubString& y); | |
431 | int operator>=(const String& x, const SubString& y); | |
432 | int operator< (const String& x, const SubString& y); | |
433 | int operator<=(const String& x, const SubString& y); | |
434 | int operator==(const String& x, const char* t); | |
435 | int operator!=(const String& x, const char* t); | |
436 | int operator> (const String& x, const char* t); | |
437 | int operator>=(const String& x, const char* t); | |
438 | int operator< (const String& x, const char* t); | |
439 | int operator<=(const String& x, const char* t); | |
440 | int operator==(const SubString& x, const String& y); | |
441 | int operator!=(const SubString& x, const String& y); | |
442 | int operator> (const SubString& x, const String& y); | |
443 | int operator>=(const SubString& x, const String& y); | |
444 | int operator< (const SubString& x, const String& y); | |
445 | int operator<=(const SubString& x, const String& y); | |
446 | int operator==(const SubString& x, const SubString& y); | |
447 | int operator!=(const SubString& x, const SubString& y); | |
448 | int operator> (const SubString& x, const SubString& y); | |
449 | int operator>=(const SubString& x, const SubString& y); | |
450 | int operator< (const SubString& x, const SubString& y); | |
451 | int operator<=(const SubString& x, const SubString& y); | |
452 | int operator==(const SubString& x, const char* t); | |
453 | int operator!=(const SubString& x, const char* t); | |
454 | int operator> (const SubString& x, const char* t); | |
455 | int operator>=(const SubString& x, const char* t); | |
456 | int operator< (const SubString& x, const char* t); | |
457 | int operator<=(const SubString& x, const char* t); | |
458 | ||
459 | #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES) | |
460 | ||
461 | ||
462 | // status reports, needed before defining other things | |
463 | ||
464 | inline int String::length() const { return rep->len; } | |
465 | inline int String::empty() const { return rep->len == 0; } | |
466 | inline const char* String::chars() const { return &(rep->s[0]); } | |
467 | inline int String::allocation() const { return rep->sz; } | |
468 | inline void String::alloc(int newsize) { rep = Sresize(rep, newsize); } | |
469 | ||
470 | inline int SubString::length() const { return len; } | |
471 | inline int SubString::empty() const { return len == 0; } | |
472 | inline const char* SubString::chars() const { return &(S.rep->s[pos]); } | |
473 | ||
474 | ||
475 | // constructors | |
476 | ||
477 | inline String::String() | |
478 | : rep(&_nilStrRep) {} | |
479 | inline String::String(const String& x) | |
480 | : rep(Scopy(0, x.rep)) {} | |
481 | inline String::String(const char* t) | |
482 | : rep(Salloc(0, t, -1, -1)) {} | |
483 | inline String::String(const char* t, int tlen) | |
484 | : rep(Salloc(0, t, tlen, tlen)) {} | |
485 | inline String::String(const SubString& y) | |
486 | : rep(Salloc(0, y.chars(), y.length(), y.length())) {} | |
487 | inline String::String(char c) | |
488 | : rep(Salloc(0, &c, 1, 1)) {} | |
489 | ||
490 | inline String::~String() { if (rep != &_nilStrRep) delete rep; } | |
491 | ||
492 | inline SubString::SubString(const SubString& x) | |
493 | :S(x.S), pos(x.pos), len(x.len) {} | |
494 | inline SubString::SubString(String& x, int first, int l) | |
495 | :S(x), pos(first), len(l) {} | |
496 | ||
497 | inline SubString::~SubString() {} | |
498 | ||
499 | // assignment | |
500 | ||
501 | inline void String::operator = (const String& y) | |
502 | { | |
503 | rep = Scopy(rep, y.rep); | |
504 | } | |
505 | ||
506 | inline void String::operator=(const char* t) | |
507 | { | |
508 | rep = Salloc(rep, t, -1, -1); | |
509 | } | |
510 | ||
511 | inline void String::operator=(const SubString& y) | |
512 | { | |
513 | rep = Salloc(rep, y.chars(), y.length(), y.length()); | |
514 | } | |
515 | ||
516 | inline void String::operator=(char c) | |
517 | { | |
518 | rep = Salloc(rep, &c, 1, 1); | |
519 | } | |
520 | ||
521 | ||
522 | inline void SubString::operator = (const char* ys) | |
523 | { | |
524 | assign(0, ys); | |
525 | } | |
526 | ||
527 | inline void SubString::operator = (char ch) | |
528 | { | |
529 | assign(0, &ch, 1); | |
530 | } | |
531 | ||
532 | inline void SubString::operator = (const String& y) | |
533 | { | |
534 | assign(y.rep, y.chars(), y.length()); | |
535 | } | |
536 | ||
537 | inline void SubString::operator = (const SubString& y) | |
538 | { | |
539 | assign(y.S.rep, y.chars(), y.length()); | |
540 | } | |
541 | ||
542 | // Zillions of cats... | |
543 | ||
544 | inline void cat(const String& x, const String& y, String& r) | |
545 | { | |
546 | r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length()); | |
547 | } | |
548 | ||
549 | inline void cat(const String& x, const SubString& y, String& r) | |
550 | { | |
551 | r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length()); | |
552 | } | |
553 | ||
554 | inline void cat(const String& x, const char* y, String& r) | |
555 | { | |
556 | r.rep = Scat(r.rep, x.chars(), x.length(), y, -1); | |
557 | } | |
558 | ||
559 | inline void cat(const String& x, char y, String& r) | |
560 | { | |
561 | r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1); | |
562 | } | |
563 | ||
564 | inline void cat(const SubString& x, const String& y, String& r) | |
565 | { | |
566 | r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length()); | |
567 | } | |
568 | ||
569 | inline void cat(const SubString& x, const SubString& y, String& r) | |
570 | { | |
571 | r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length()); | |
572 | } | |
573 | ||
574 | inline void cat(const SubString& x, const char* y, String& r) | |
575 | { | |
576 | r.rep = Scat(r.rep, x.chars(), x.length(), y, -1); | |
577 | } | |
578 | ||
579 | inline void cat(const SubString& x, char y, String& r) | |
580 | { | |
581 | r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1); | |
582 | } | |
583 | ||
584 | inline void cat(const char* x, const String& y, String& r) | |
585 | { | |
586 | r.rep = Scat(r.rep, x, -1, y.chars(), y.length()); | |
587 | } | |
588 | ||
589 | inline void cat(const char* x, const SubString& y, String& r) | |
590 | { | |
591 | r.rep = Scat(r.rep, x, -1, y.chars(), y.length()); | |
592 | } | |
593 | ||
594 | inline void cat(const char* x, const char* y, String& r) | |
595 | { | |
596 | r.rep = Scat(r.rep, x, -1, y, -1); | |
597 | } | |
598 | ||
599 | inline void cat(const char* x, char y, String& r) | |
600 | { | |
601 | r.rep = Scat(r.rep, x, -1, &y, 1); | |
602 | } | |
603 | ||
604 | inline void cat(const String& a, const String& x, const String& y, String& r) | |
605 | { | |
606 | r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length()); | |
607 | } | |
608 | ||
609 | inline void cat(const String& a, const String& x, const SubString& y, String& r) | |
610 | { | |
611 | r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length()); | |
612 | } | |
613 | ||
614 | inline void cat(const String& a, const String& x, const char* y, String& r) | |
615 | { | |
616 | r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1); | |
617 | } | |
618 | ||
619 | inline void cat(const String& a, const String& x, char y, String& r) | |
620 | { | |
621 | r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1); | |
622 | } | |
623 | ||
624 | inline void cat(const String& a, const SubString& x, const String& y, String& r) | |
625 | { | |
626 | r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length()); | |
627 | } | |
628 | ||
629 | inline void cat(const String& a, const SubString& x, const SubString& y, String& r) | |
630 | { | |
631 | r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length()); | |
632 | } | |
633 | ||
634 | inline void cat(const String& a, const SubString& x, const char* y, String& r) | |
635 | { | |
636 | r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1); | |
637 | } | |
638 | ||
639 | inline void cat(const String& a, const SubString& x, char y, String& r) | |
640 | { | |
641 | r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1); | |
642 | } | |
643 | ||
644 | inline void cat(const String& a, const char* x, const String& y, String& r) | |
645 | { | |
646 | r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length()); | |
647 | } | |
648 | ||
649 | inline void cat(const String& a, const char* x, const SubString& y, String& r) | |
650 | { | |
651 | r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length()); | |
652 | } | |
653 | ||
654 | inline void cat(const String& a, const char* x, const char* y, String& r) | |
655 | { | |
656 | r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y, -1); | |
657 | } | |
658 | ||
659 | inline void cat(const String& a, const char* x, char y, String& r) | |
660 | { | |
661 | r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, &y, 1); | |
662 | } | |
663 | ||
664 | ||
665 | inline void cat(const char* a, const String& x, const String& y, String& r) | |
666 | { | |
667 | r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length()); | |
668 | } | |
669 | ||
670 | inline void cat(const char* a, const String& x, const SubString& y, String& r) | |
671 | { | |
672 | r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length()); | |
673 | } | |
674 | ||
675 | inline void cat(const char* a, const String& x, const char* y, String& r) | |
676 | { | |
677 | r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1); | |
678 | } | |
679 | ||
680 | inline void cat(const char* a, const String& x, char y, String& r) | |
681 | { | |
682 | r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1); | |
683 | } | |
684 | ||
685 | inline void cat(const char* a, const SubString& x, const String& y, String& r) | |
686 | { | |
687 | r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length()); | |
688 | } | |
689 | ||
690 | inline void cat(const char* a, const SubString& x, const SubString& y, String& r) | |
691 | { | |
692 | r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length()); | |
693 | } | |
694 | ||
695 | inline void cat(const char* a, const SubString& x, const char* y, String& r) | |
696 | { | |
697 | r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1); | |
698 | } | |
699 | ||
700 | inline void cat(const char* a, const SubString& x, char y, String& r) | |
701 | { | |
702 | r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1); | |
703 | } | |
704 | ||
705 | inline void cat(const char* a, const char* x, const String& y, String& r) | |
706 | { | |
707 | r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length()); | |
708 | } | |
709 | ||
710 | inline void cat(const char* a, const char* x, const SubString& y, String& r) | |
711 | { | |
712 | r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length()); | |
713 | } | |
714 | ||
715 | inline void cat(const char* a, const char* x, const char* y, String& r) | |
716 | { | |
717 | r.rep = Scat(r.rep, a, -1, x, -1, y, -1); | |
718 | } | |
719 | ||
720 | inline void cat(const char* a, const char* x, char y, String& r) | |
721 | { | |
722 | r.rep = Scat(r.rep, a, -1, x, -1, &y, 1); | |
723 | } | |
724 | ||
725 | ||
726 | // operator versions | |
727 | ||
728 | inline void String::operator +=(const String& y) | |
729 | { | |
730 | cat(*this, y, *this); | |
731 | } | |
732 | ||
733 | inline void String::operator +=(const SubString& y) | |
734 | { | |
735 | cat(*this, y, *this); | |
736 | } | |
737 | ||
738 | inline void String::operator += (const char* y) | |
739 | { | |
740 | cat(*this, y, *this); | |
741 | } | |
742 | ||
743 | inline void String:: operator +=(char y) | |
744 | { | |
745 | cat(*this, y, *this); | |
746 | } | |
747 | ||
748 | // constructive concatenation | |
749 | ||
750 | #if defined(__GNUG__) && !defined(NO_NRV) | |
751 | ||
752 | inline String operator + (const String& x, const String& y) return r; | |
753 | { | |
754 | cat(x, y, r); | |
755 | } | |
756 | ||
757 | inline String operator + (const String& x, const SubString& y) return r; | |
758 | { | |
759 | cat(x, y, r); | |
760 | } | |
761 | ||
762 | inline String operator + (const String& x, const char* y) return r; | |
763 | { | |
764 | cat(x, y, r); | |
765 | } | |
766 | ||
767 | inline String operator + (const String& x, char y) return r; | |
768 | { | |
769 | cat(x, y, r); | |
770 | } | |
771 | ||
772 | inline String operator + (const SubString& x, const String& y) return r; | |
773 | { | |
774 | cat(x, y, r); | |
775 | } | |
776 | ||
777 | inline String operator + (const SubString& x, const SubString& y) return r; | |
778 | { | |
779 | cat(x, y, r); | |
780 | } | |
781 | ||
782 | inline String operator + (const SubString& x, const char* y) return r; | |
783 | { | |
784 | cat(x, y, r); | |
785 | } | |
786 | ||
787 | inline String operator + (const SubString& x, char y) return r; | |
788 | { | |
789 | cat(x, y, r); | |
790 | } | |
791 | ||
792 | inline String operator + (const char* x, const String& y) return r; | |
793 | { | |
794 | cat(x, y, r); | |
795 | } | |
796 | ||
797 | inline String operator + (const char* x, const SubString& y) return r; | |
798 | { | |
799 | cat(x, y, r); | |
800 | } | |
801 | ||
802 | inline String reverse(const String& x) return r; | |
803 | { | |
804 | r.rep = Sreverse(x.rep, r.rep); | |
805 | } | |
806 | ||
807 | inline String upcase(const String& x) return r; | |
808 | { | |
809 | r.rep = Supcase(x.rep, r.rep); | |
810 | } | |
811 | ||
812 | inline String downcase(const String& x) return r; | |
813 | { | |
814 | r.rep = Sdowncase(x.rep, r.rep); | |
815 | } | |
816 | ||
817 | inline String capitalize(const String& x) return r; | |
818 | { | |
819 | r.rep = Scapitalize(x.rep, r.rep); | |
820 | } | |
821 | ||
822 | #else /* NO_NRV */ | |
823 | ||
824 | inline String operator + (const String& x, const String& y) | |
825 | { | |
826 | String r; cat(x, y, r); return r; | |
827 | } | |
828 | ||
829 | inline String operator + (const String& x, const SubString& y) | |
830 | { | |
831 | String r; cat(x, y, r); return r; | |
832 | } | |
833 | ||
834 | inline String operator + (const String& x, const char* y) | |
835 | { | |
836 | String r; cat(x, y, r); return r; | |
837 | } | |
838 | ||
839 | inline String operator + (const String& x, char y) | |
840 | { | |
841 | String r; cat(x, y, r); return r; | |
842 | } | |
843 | ||
844 | inline String operator + (const SubString& x, const String& y) | |
845 | { | |
846 | String r; cat(x, y, r); return r; | |
847 | } | |
848 | ||
849 | inline String operator + (const SubString& x, const SubString& y) | |
850 | { | |
851 | String r; cat(x, y, r); return r; | |
852 | } | |
853 | ||
854 | inline String operator + (const SubString& x, const char* y) | |
855 | { | |
856 | String r; cat(x, y, r); return r; | |
857 | } | |
858 | ||
859 | inline String operator + (const SubString& x, char y) | |
860 | { | |
861 | String r; cat(x, y, r); return r; | |
862 | } | |
863 | ||
864 | inline String operator + (const char* x, const String& y) | |
865 | { | |
866 | String r; cat(x, y, r); return r; | |
867 | } | |
868 | ||
869 | inline String operator + (const char* x, const SubString& y) | |
870 | { | |
871 | String r; cat(x, y, r); return r; | |
872 | } | |
873 | ||
874 | inline String reverse(const String& x) | |
875 | { | |
876 | String r; r.rep = Sreverse(x.rep, r.rep); return r; | |
877 | } | |
878 | ||
879 | inline String upcase(const String& x) | |
880 | { | |
881 | String r; r.rep = Supcase(x.rep, r.rep); return r; | |
882 | } | |
883 | ||
884 | inline String downcase(const String& x) | |
885 | { | |
886 | String r; r.rep = Sdowncase(x.rep, r.rep); return r; | |
887 | } | |
888 | ||
889 | inline String capitalize(const String& x) | |
890 | { | |
891 | String r; r.rep = Scapitalize(x.rep, r.rep); return r; | |
892 | } | |
893 | ||
894 | #endif | |
895 | ||
896 | // prepend | |
897 | ||
898 | inline void String::prepend(const String& y) | |
899 | { | |
900 | rep = Sprepend(rep, y.chars(), y.length()); | |
901 | } | |
902 | ||
903 | inline void String::prepend(const char* y) | |
904 | { | |
905 | rep = Sprepend(rep, y, -1); | |
906 | } | |
907 | ||
908 | inline void String::prepend(char y) | |
909 | { | |
910 | rep = Sprepend(rep, &y, 1); | |
911 | } | |
912 | ||
913 | inline void String::prepend(const SubString& y) | |
914 | { | |
915 | rep = Sprepend(rep, y.chars(), y.length()); | |
916 | } | |
917 | ||
918 | // misc transformations | |
919 | ||
920 | ||
921 | inline void String::reverse() | |
922 | { | |
923 | rep = Sreverse(rep, rep); | |
924 | } | |
925 | ||
926 | ||
927 | inline void String::upcase() | |
928 | { | |
929 | rep = Supcase(rep, rep); | |
930 | } | |
931 | ||
932 | ||
933 | inline void String::downcase() | |
934 | { | |
935 | rep = Sdowncase(rep, rep); | |
936 | } | |
937 | ||
938 | ||
939 | inline void String::capitalize() | |
940 | { | |
941 | rep = Scapitalize(rep, rep); | |
942 | } | |
943 | ||
944 | // element extraction | |
945 | ||
946 | inline char& String::operator [] (int i) | |
947 | { | |
948 | if (((unsigned)i) >= length()) error("invalid index"); | |
949 | return rep->s[i]; | |
950 | } | |
951 | ||
952 | inline char String::elem (int i) const | |
953 | { | |
954 | if (((unsigned)i) >= length()) error("invalid index"); | |
955 | return rep->s[i]; | |
956 | } | |
957 | ||
958 | inline char String::firstchar() const | |
959 | { | |
960 | return elem(0); | |
961 | } | |
962 | ||
963 | inline char String::lastchar() const | |
964 | { | |
965 | return elem(length() - 1); | |
966 | } | |
967 | ||
968 | // searching | |
969 | ||
970 | inline int String::index(char c, int startpos) const | |
971 | { | |
972 | return search(startpos, length(), c); | |
973 | } | |
974 | ||
975 | inline int String::index(const char* t, int startpos) const | |
976 | { | |
977 | return search(startpos, length(), t); | |
978 | } | |
979 | ||
980 | inline int String::index(const String& y, int startpos) const | |
981 | { | |
982 | return search(startpos, length(), y.chars(), y.length()); | |
983 | } | |
984 | ||
985 | inline int String::index(const SubString& y, int startpos) const | |
986 | { | |
987 | return search(startpos, length(), y.chars(), y.length()); | |
988 | } | |
989 | ||
990 | inline int String::index(const Regex& r, int startpos) const | |
991 | { | |
992 | int unused; return r.search(chars(), length(), unused, startpos); | |
993 | } | |
994 | ||
995 | inline int String::contains(char c) const | |
996 | { | |
997 | return search(0, length(), c) >= 0; | |
998 | } | |
999 | ||
1000 | inline int String::contains(const char* t) const | |
1001 | { | |
1002 | return search(0, length(), t) >= 0; | |
1003 | } | |
1004 | ||
1005 | inline int String::contains(const String& y) const | |
1006 | { | |
1007 | return search(0, length(), y.chars(), y.length()) >= 0; | |
1008 | } | |
1009 | ||
1010 | inline int String::contains(const SubString& y) const | |
1011 | { | |
1012 | return search(0, length(), y.chars(), y.length()) >= 0; | |
1013 | } | |
1014 | ||
1015 | inline int String::contains(char c, int p) const | |
1016 | { | |
1017 | return match(p, length(), 0, &c, 1) >= 0; | |
1018 | } | |
1019 | ||
1020 | inline int String::contains(const char* t, int p) const | |
1021 | { | |
1022 | return match(p, length(), 0, t) >= 0; | |
1023 | } | |
1024 | ||
1025 | inline int String::contains(const String& y, int p) const | |
1026 | { | |
1027 | return match(p, length(), 0, y.chars(), y.length()) >= 0; | |
1028 | } | |
1029 | ||
1030 | inline int String::contains(const SubString& y, int p) const | |
1031 | { | |
1032 | return match(p, length(), 0, y.chars(), y.length()) >= 0; | |
1033 | } | |
1034 | ||
1035 | inline int String::contains(const Regex& r) const | |
1036 | { | |
1037 | int unused; return r.search(chars(), length(), unused, 0) >= 0; | |
1038 | } | |
1039 | ||
1040 | inline int String::contains(const Regex& r, int p) const | |
1041 | { | |
1042 | return r.match(chars(), length(), p) >= 0; | |
1043 | } | |
1044 | ||
1045 | ||
1046 | inline int String::matches(const SubString& y, int p) const | |
1047 | { | |
1048 | return match(p, length(), 1, y.chars(), y.length()) >= 0; | |
1049 | } | |
1050 | ||
1051 | inline int String::matches(const String& y, int p) const | |
1052 | { | |
1053 | return match(p, length(), 1, y.chars(), y.length()) >= 0; | |
1054 | } | |
1055 | ||
1056 | inline int String::matches(const char* t, int p) const | |
1057 | { | |
1058 | return match(p, length(), 1, t) >= 0; | |
1059 | } | |
1060 | ||
1061 | inline int String::matches(char c, int p) const | |
1062 | { | |
1063 | return match(p, length(), 1, &c, 1) >= 0; | |
1064 | } | |
1065 | ||
1066 | inline int String::matches(const Regex& r, int p) const | |
1067 | { | |
1068 | int l = (p < 0)? -p : length() - p; | |
1069 | return r.match(chars(), length(), p) == l; | |
1070 | } | |
1071 | ||
1072 | ||
1073 | inline int SubString::contains(const char* t) const | |
1074 | { | |
1075 | return S.search(pos, pos+len, t) >= 0; | |
1076 | } | |
1077 | ||
1078 | inline int SubString::contains(const String& y) const | |
1079 | { | |
1080 | return S.search(pos, pos+len, y.chars(), y.length()) >= 0; | |
1081 | } | |
1082 | ||
1083 | inline int SubString::contains(const SubString& y) const | |
1084 | { | |
1085 | return S.search(pos, pos+len, y.chars(), y.length()) >= 0; | |
1086 | } | |
1087 | ||
1088 | inline int SubString::contains(char c) const | |
1089 | { | |
1090 | return S.search(pos, pos+len, 0, c) >= 0; | |
1091 | } | |
1092 | ||
1093 | inline int SubString::contains(const Regex& r) const | |
1094 | { | |
1095 | int unused; return r.search(chars(), len, unused, 0) >= 0; | |
1096 | } | |
1097 | ||
1098 | inline int SubString::matches(const Regex& r) const | |
1099 | { | |
1100 | return r.match(chars(), len, 0) == len; | |
1101 | } | |
1102 | ||
1103 | ||
1104 | inline int String::gsub(const String& pat, const String& r) | |
1105 | { | |
1106 | return _gsub(pat.chars(), pat.length(), r.chars(), r.length()); | |
1107 | } | |
1108 | ||
1109 | inline int String::gsub(const SubString& pat, const String& r) | |
1110 | { | |
1111 | return _gsub(pat.chars(), pat.length(), r.chars(), r.length()); | |
1112 | } | |
1113 | ||
1114 | inline int String::gsub(const Regex& pat, const String& r) | |
1115 | { | |
1116 | return _gsub(pat, r.chars(), r.length()); | |
1117 | } | |
1118 | ||
1119 | inline int String::gsub(const char* pat, const String& r) | |
1120 | { | |
1121 | return _gsub(pat, -1, r.chars(), r.length()); | |
1122 | } | |
1123 | ||
1124 | inline int String::gsub(const char* pat, const char* r) | |
1125 | { | |
1126 | return _gsub(pat, -1, r, -1); | |
1127 | } | |
1128 | ||
1129 | ||
1130 | inline String::operator const char*() const | |
1131 | { | |
1132 | return str(chars()); | |
1133 | } | |
1134 | ||
1135 | inline ostream& operator<<(ostream& s, const String& x) | |
1136 | { | |
1137 | #ifdef VMS | |
1138 | s << x.chars(); return s; | |
1139 | #else | |
1140 | s.put(x.chars()); return s; | |
1141 | #endif | |
1142 | ||
1143 | } | |
1144 | ||
1145 | // a zillion comparison operators | |
1146 | ||
1147 | inline int operator==(const String& x, const String& y) | |
1148 | { | |
1149 | return compare(x, y) == 0; | |
1150 | } | |
1151 | ||
1152 | inline int operator!=(const String& x, const String& y) | |
1153 | { | |
1154 | return compare(x, y) != 0; | |
1155 | } | |
1156 | ||
1157 | inline int operator>(const String& x, const String& y) | |
1158 | { | |
1159 | return compare(x, y) > 0; | |
1160 | } | |
1161 | ||
1162 | inline int operator>=(const String& x, const String& y) | |
1163 | { | |
1164 | return compare(x, y) >= 0; | |
1165 | } | |
1166 | ||
1167 | inline int operator<(const String& x, const String& y) | |
1168 | { | |
1169 | return compare(x, y) < 0; | |
1170 | } | |
1171 | ||
1172 | inline int operator<=(const String& x, const String& y) | |
1173 | { | |
1174 | return compare(x, y) <= 0; | |
1175 | } | |
1176 | ||
1177 | inline int operator==(const String& x, const SubString& y) | |
1178 | { | |
1179 | return compare(x, y) == 0; | |
1180 | } | |
1181 | ||
1182 | inline int operator!=(const String& x, const SubString& y) | |
1183 | { | |
1184 | return compare(x, y) != 0; | |
1185 | } | |
1186 | ||
1187 | inline int operator>(const String& x, const SubString& y) | |
1188 | { | |
1189 | return compare(x, y) > 0; | |
1190 | } | |
1191 | ||
1192 | inline int operator>=(const String& x, const SubString& y) | |
1193 | { | |
1194 | return compare(x, y) >= 0; | |
1195 | } | |
1196 | ||
1197 | inline int operator<(const String& x, const SubString& y) | |
1198 | { | |
1199 | return compare(x, y) < 0; | |
1200 | } | |
1201 | ||
1202 | inline int operator<=(const String& x, const SubString& y) | |
1203 | { | |
1204 | return compare(x, y) <= 0; | |
1205 | } | |
1206 | ||
1207 | inline int operator==(const String& x, const char* t) | |
1208 | { | |
1209 | return compare(x, t) == 0; | |
1210 | } | |
1211 | ||
1212 | inline int operator!=(const String& x, const char* t) | |
1213 | { | |
1214 | return compare(x, t) != 0; | |
1215 | } | |
1216 | ||
1217 | inline int operator>(const String& x, const char* t) | |
1218 | { | |
1219 | return compare(x, t) > 0; | |
1220 | } | |
1221 | ||
1222 | inline int operator>=(const String& x, const char* t) | |
1223 | { | |
1224 | return compare(x, t) >= 0; | |
1225 | } | |
1226 | ||
1227 | inline int operator<(const String& x, const char* t) | |
1228 | { | |
1229 | return compare(x, t) < 0; | |
1230 | } | |
1231 | ||
1232 | inline int operator<=(const String& x, const char* t) | |
1233 | { | |
1234 | return compare(x, t) <= 0; | |
1235 | } | |
1236 | ||
1237 | inline int operator==(const SubString& x, const String& y) | |
1238 | { | |
1239 | return compare(y, x) == 0; | |
1240 | } | |
1241 | ||
1242 | inline int operator!=(const SubString& x, const String& y) | |
1243 | { | |
1244 | return compare(y, x) != 0; | |
1245 | } | |
1246 | ||
1247 | inline int operator>(const SubString& x, const String& y) | |
1248 | { | |
1249 | return compare(y, x) < 0; | |
1250 | } | |
1251 | ||
1252 | inline int operator>=(const SubString& x, const String& y) | |
1253 | { | |
1254 | return compare(y, x) <= 0; | |
1255 | } | |
1256 | ||
1257 | inline int operator<(const SubString& x, const String& y) | |
1258 | { | |
1259 | return compare(y, x) > 0; | |
1260 | } | |
1261 | ||
1262 | inline int operator<=(const SubString& x, const String& y) | |
1263 | { | |
1264 | return compare(y, x) >= 0; | |
1265 | } | |
1266 | ||
1267 | inline int operator==(const SubString& x, const SubString& y) | |
1268 | { | |
1269 | return compare(x, y) == 0; | |
1270 | } | |
1271 | ||
1272 | inline int operator!=(const SubString& x, const SubString& y) | |
1273 | { | |
1274 | return compare(x, y) != 0; | |
1275 | } | |
1276 | ||
1277 | inline int operator>(const SubString& x, const SubString& y) | |
1278 | { | |
1279 | return compare(x, y) > 0; | |
1280 | } | |
1281 | ||
1282 | inline int operator>=(const SubString& x, const SubString& y) | |
1283 | { | |
1284 | return compare(x, y) >= 0; | |
1285 | } | |
1286 | ||
1287 | inline int operator<(const SubString& x, const SubString& y) | |
1288 | { | |
1289 | return compare(x, y) < 0; | |
1290 | } | |
1291 | ||
1292 | inline int operator<=(const SubString& x, const SubString& y) | |
1293 | { | |
1294 | return compare(x, y) <= 0; | |
1295 | } | |
1296 | ||
1297 | inline int operator==(const SubString& x, const char* t) | |
1298 | { | |
1299 | return compare(x, t) == 0; | |
1300 | } | |
1301 | ||
1302 | inline int operator!=(const SubString& x, const char* t) | |
1303 | { | |
1304 | return compare(x, t) != 0; | |
1305 | } | |
1306 | ||
1307 | inline int operator>(const SubString& x, const char* t) | |
1308 | { | |
1309 | return compare(x, t) > 0; | |
1310 | } | |
1311 | ||
1312 | inline int operator>=(const SubString& x, const char* t) | |
1313 | { | |
1314 | return compare(x, t) >= 0; | |
1315 | } | |
1316 | ||
1317 | inline int operator<(const SubString& x, const char* t) | |
1318 | { | |
1319 | return compare(x, t) < 0; | |
1320 | } | |
1321 | ||
1322 | inline int operator<=(const SubString& x, const char* t) | |
1323 | { | |
1324 | return compare(x, t) <= 0; | |
1325 | } | |
1326 | ||
1327 | ||
1328 | // a helper needed by at, before, etc. | |
1329 | ||
1330 | inline SubString String::_substr(int first, int l) | |
1331 | { | |
1332 | if (first < 0 || (unsigned)(first + l) > length()) | |
1333 | return SubString(_nilString, 0, 0) ; | |
1334 | else | |
1335 | return SubString(*this, first, l); | |
1336 | } | |
1337 | ||
1338 | ||
1339 | #endif | |
1340 | ||
1341 | #endif |